#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "calculator.hpp"
#include "Deamon.hpp"
// #include"CommandExec.hpp"
#include <memory>

// 计算模块
//vesion-1和vesion-2用到的gcal 
//Calculator gcal;
// package一定有完整的报文吗？不一定
// 不完整->返回继续读
// 完整->提取->反序列化->Request->计算模块，进行处理->总结解析把结果返回
// 下面是一次处理一个报文
//  std::string Entry(std::string& package)
//  {
//      //判断代码的完整性
//      std::string message;
//      bool rs=Decode(package,&message);
//      if(!rs || !message.empty())return std::string();

//     //2.反序列化
//     Request req;
//     if(!req.Deserialize(message))return std::string();//反序列化失败

//     //3.计算
//     Response resp=gcal.Execute(req);

//     //4.错误码判断，并序列化返回
//     std::string result_str;
//     resp.Serialize(result_str);

//     //5.添加报头
//     Encode(result_str);

//     return result_str;
// }

// vesion-2 你有多少报文我就处理多少完整的报文
//  std::string Entry(std::string &package)
//     {
//         // 判断代码的完整性
//         std::string message;
//         std::string respstr;
//         while (Decode(package, &message))
//         {
//             if (!message.empty())
//                 break;

//             // 2.反序列化
//             Request req;
//             if (!req.Deserialize(message))
//                 break; // 反序列化失败

//             // 3.计算
//             Response resp = gcal.Execute(req);

//             // 4.错误码判断，并序列化返回
//             std::string result_str;
//             resp.Serialize(result_str);

//             // 5.添加报头
//             Encode(result_str);

//             // 6.拼接应答
//             respstr += result_str;
//         }

//         return respstr;
//     }

//vesion-3  对函数进行封装
using cal_fun = std::function<Response(const Request &req)>;
class Parse
{
public:
    Parse(cal_fun c) : _cal(c) {}
    std::string Entry(std::string &package)
    {
        // 判断代码的完整性
        std::string message;
        std::string respstr;
        while (Decode(package, &message))
        {
            if (message.empty())
                break;

            // 2.反序列化
            Request req;
            if (!req.Deserialize(message))
                break; // 反序列化失败
            std::cout << "————————————————————" << std::endl;
            req.Print();
            std::cout << "————————————————————" << std::endl;

            // 3.计算
            Response resp = _cal(req);

            // 4.错误码判断，并序列化返回
            std::string result_str;
            resp.Serialize(result_str);
            std::cout << "———————————————————" << std::endl;
            std::cout << result_str << std::endl;
            std::cout << "———————————————————" << std::endl;
            // 5.添加报头
            Encode(result_str);

            // 6.拼接应答
            respstr += result_str;
        }

        return respstr;
    }

private:
    cal_fun _cal;
};

int main()
{
    //远程指令
    // CommandExec cmd;
    // std::unique_ptr<TcpServer> tsvr=std::make_unique <TcpServer>([&cmd](std::string cmdstr){return cmd.Execute(cmdstr);});

    //远程计算器
    //vesion-1和vesion-2
    // std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>(Entry);

    //vesion-3
    Daemon(false,false);
    //1.计算模块
    Calculator mycal;
    //2.解析对象
    Parse myParse([&mycal](const Request &req){
        return mycal.Execute(req);
    });
    //3.通信模块
    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>([&myParse](std::string &package){
        return myParse.Entry(package); 
    });

    tsvr->InitServer();
    tsvr->Start();

    return 0;
}